using System;
using System.Text;
using System.Reflection;
using System.Data.SqlClient;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;

using Open.Data.Persistence;


namespace Open.Data.Persistence.Testing
{
    [TestClass]
    public class InheritanceTests
    {
        //Make sure that an object is only selected when all keys are in the inheritance chain
        [TestMethod, ExpectedException(typeof(RecordNotFoundException))]
        public void InheritanceSelectPartial()
        {
            Command command = Singleton.Instance.GetContext().CreateCommand();

            Person person = new Person();
            person.Id = 101;
            person.FirstNames = "Joe";
            person.Insert(command);

            Customer customer = new Customer();
            customer.Id = 101;
            customer.Select(command); //Should throw exception
        }

        //Test that an object can be inserted when certain keys are available down the chain
        [TestMethod, ExpectedException(typeof(DuplicateKeyException))]
        public void InheritanceInsertCustomerPartial()
        {
            Command command = Singleton.Instance.GetContext().CreateCommand();

            Person person = new Person();
            person.Id = 102;
            person.FirstNames = "Mark";
            person.Insert(command);

            Customer customer = new Customer();
            customer.Id = 102;
            customer.FirstNames = "Bob";
            customer.Insert(command);
        }

        //Test the promotion of an object does not cause a duplicate key error
        [TestMethod]
        public void InheritancePromoteCustomer()
        {
            Command command = Singleton.Instance.GetContext().CreateCommand();

            Person person = new Person();
            person.Id = 103;
            person.FirstNames = "Paul";
            person.Insert(command);

            Customer customer = new Customer();
            customer.Id = 103;
            customer.FirstNames = "Bob";

            customer.InsertPartial(command);

        }

        [TestMethod, ExpectedException(typeof(RecordNotFoundException))]
        public void InheritanceDemoteCustomer()
        {
            Command command = Singleton.Instance.GetContext().CreateCommand();

            Person person = new Person();
            person.Id = 104;
            person.FirstNames = "Paul";
            person.Insert(command);

            Customer customer = new Customer();
            customer.Id = 104;
            customer.FirstNames = "Bob";

            customer.InsertPartial(command);

            customer = new Customer();
            customer.Id = 104;
            customer.DeletePartial(command);

            try
            {
                person = new Person();
                person.Id = 104;
                person.Select(command);
            }
            catch (Exception ex)
            {
                throw new Exception("Person should be selected after demotion.", ex);
            }

            customer = new Customer();
            customer.Id = 104;
            customer.Select(command);
        }

        [TestMethod]
        public void InheritanceCreateFromAbstract()
        {
            Command command = Singleton.Instance.GetContext().CreateCommand();

            var boat = new Boat() { Name = "Dignity" };
            command.Insert(boat);
            Assert.IsTrue(boat.Id > 0, "Boat Entity identity not set.");

            var boat2 = new Boat();
            boat2.Id = boat.Id;
            command.Select(boat2);
            Assert.IsTrue(boat2.Name == boat.Name, "Boat name not saved.");

            var yacht = new Yacht() { Name = "Titanic", Length = 12, Masts = 1 };
            command.Insert(yacht);
            Assert.IsTrue(yacht.Id > 0, "Yacht Entity identity not set.");

            var yacht2 = new Yacht();
            yacht2.Id = yacht.Id;
            command.Select(yacht2);
            Assert.IsTrue(yacht2.Name == yacht.Name, "Yacht name not saved."); //From Boat
            Assert.IsTrue(yacht2.Masts == yacht.Masts, "Yacht masts not saved."); //From Sailboat
            Assert.IsTrue(yacht2.Length == yacht.Length, "Yacht length not saved."); 

            var racingYacht = new RacingYacht() { Name = "Sprint", Length=40, Masts= 2, Speed= 50};
            command.Insert(racingYacht);
            Assert.IsTrue(racingYacht.Id > 0, "RacingYacht Entity identity not set.");

            var racingYacht2 = new RacingYacht();
            racingYacht2.Id = racingYacht.Id;
            command.Select(racingYacht2);

            Assert.IsTrue(racingYacht2.Name == racingYacht.Name, "RacingYacht name not saved."); //From Boat
            Assert.IsTrue(racingYacht2.Masts == racingYacht.Masts, "RacingYacht masts not saved."); //From SailBoat
            Assert.IsTrue(racingYacht2.Length == racingYacht.Length, "RacingYacht length not saved."); //From Yacht
            Assert.IsTrue(racingYacht2.Speed == racingYacht.Speed, "RacingYacht speed not saved.");
        }
    }
}
